import time
from typing import TypeVar, Generic, Optional, Any

from pydantic import BaseModel, Field

from app.core.response.ResponseCode import ResponseCode

# 1. 定义一个泛型类型变量 T
T = TypeVar('T')

class ResponseResult(BaseModel, Generic[T]):
    """
    统一的 API 响应模型 (Pydantic 实现)
    - Generic[T] 使其支持泛型数据
    - BaseModel 提供了数据验证、序列化等功能
    """
    code: int
    message: str
    data: Optional[T] = None  # data 可以是泛型 T，也可以是 None

    timestamps: int = Field(default_factory=lambda: int(time.time() * 1000))

    @classmethod
    def build(cls, response_code: ResponseCode, data: Optional[T] = None) -> 'ResponseResult[T]':
        return cls(code=response_code.code, message=response_code.message, data=data)

    @classmethod
    def build_msg(cls, code: int, message: str) -> 'ResponseResult[None]':
        return cls(code=code, message=message, data=None)

    @classmethod
    def ok(cls) -> 'ResponseResult[None]':
        return cls.build(ResponseCode.SUCCESS)
    
    @classmethod
    def ok_msg(cls, message: str) -> 'ResponseResult[None]':
        return cls(code=ResponseCode.SUCCESS.code, message=message)

    @classmethod
    def ok_data(cls, data: Any) -> 'ResponseResult[Any]':
        # 处理list或其他类型数据的序列化问题
        if isinstance(data, list):
            # 如果是对象列表，尝试转换为字典列表
            serialized_data = []
            for item in data:
                if hasattr(item, 'dict') and callable(getattr(item, 'dict')):
                    serialized_data.append(item.dict())
                elif hasattr(item, '__dict__'):
                    serialized_data.append(item.__dict__)
                else:
                    serialized_data.append(item)
            return cls.build(ResponseCode.SUCCESS, data=serialized_data)
        else:
            return cls.build(ResponseCode.SUCCESS, data=data)

    @classmethod
    def fail(cls, response_code: ResponseCode = ResponseCode.FAIL,
             message: Optional[str] = None) -> 'ResponseResult[None]':
        final_message = message if message is not None else response_code.message
        return cls(code=response_code.code, message=final_message, data=None)